//
//  interitance_exercise.hpp
//  learnC++
//
//  Created by liuzhibing on 2018/6/13.
//  Copyright © 2018年 yunfan.com. All rights reserved.
//

#ifndef interitance_exercise_hpp
#define interitance_exercise_hpp

#include <stdio.h>
#include <iostream>
#include <string>
#include <cstdlib> // for rand() and srand()
#include <ctime> // for time()


int getRandomNumber(int min, int max);


class Creature
{
protected:
    std::string m_name;
    char m_symbol;
    int m_health;
    int m_damage;
    int m_gold;
    
public:
    Creature(std::string name, char symbol, int health, int damage, int gold) :
    m_name(name), m_symbol(symbol), m_health(health), m_damage(damage), m_gold(gold)
    {
    }
    
    char getSymbol() { return m_symbol; }
    const std::string& getName() { return m_name; }
    bool isDead() { return m_health <= 0; }
    int getGold() { return m_gold; }
    void addGold(int gold) { m_gold += gold;  }
    void reduceHealth(int health) { m_health -= health;  }
    int getHealth() { return m_health; }
    int getDamage() { return m_damage;  }
};

class Player : public Creature
{
    int m_level = 1;
    
public:
    Player(std::string name)
    : Creature(name, '@', 10, 1, 0)
    {
    }
    
    void levelUp()
    {
        ++m_level;
        ++m_damage;
    }
    
    int getLevel() { return m_level; }
    bool hasWon() { return m_level >= 20; }
};



class Monster : public Creature
{
public:
    enum Type
    {
        DRAGON,
        ORC,
        SLIME,
        MAX_TYPES
    };
    
    struct MonsterData
    {
        const char* name;
        char symbol;
        int health;
        int damage;
        int gold;
    };
    
    static MonsterData monsterData[MAX_TYPES];
    Type m_type;
    
    Monster(Type type)
    : Creature(monsterData[type].name, monsterData[type].symbol, monsterData[type].health, monsterData[type].damage, monsterData[type].gold), m_type(type)
    {
    }
    
    static Monster getRandomMonster()
    {
        int num = getRandomNumber(0, MAX_TYPES - 1);
        return Monster(static_cast<Type>(num));
    }
};

void attackMonster(Player &p, Monster &m);
void attackPlayer(Monster &m, Player &p);
void fightMonster(Player &p);

/*
 srand(static_cast<unsigned int>(time(0))); // set initial seed value to system clock
 rand(); // get rid of first result
 
 std::cout << "Enter your name: ";
 std::string playerName;
 std::cin >> playerName;
 
 Player p(playerName);
 std::cout << "Welcome, " << p.getName() << '\n';
 
 // If the player isn't dead and hasn't won yet, the game continues
 while (!p.isDead() && !p.hasWon())
 fightMonster(p);
 
 // At this point, the player is either dead or has won
 if (p.isDead())
 {
 std::cout << "You died at level " << p.getLevel() << " and with " << p.getGold() << " gold.\n";
 std::cout << "Too bad you can't take it with you!\n";
 }
 else
 {
 std::cout << "You won the game with " << p.getGold() << " gold!\n";
 }
 
 */



#endif /* interitance_exercise_hpp */
